package com.heima.collect.arrayList;

import java.lang.reflect.Field;
import java.util.ArrayList;

/**
 * 1. ArrayList的初始化
 *      无参构造情况下：默认初始化长度为0的数组赋值给elementData;
 *      带参构造情况下：创建一个指定长度的数组赋值给elementData;
 *
 * 2. ArrayList的添加过程
 *      1. 判断当前的elementData数组有没有满
 *      2. 满了，就会调用grow()进行扩容
 *      3. 没满：就会将要添加的元素存入elementData数组的size对应的索引位置
 *      4. 将size的值+1
 *
 * 3. ArrayList的扩容机制
 *      扩容方法：grow()
 *      扩容系数： 新容量 = 老容量 + 老容量的一半 （1.5倍）
 *
 *      考试： 问无参构造情况下，ArrayList第三次扩容，底层数组长度是多少？
 *                1       2      3       4
 *              0 --> 10  --> 15 --> 22  --> 33
 *
 */
public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        int elementDataLength = getElementDataLength(list);
        System.out.println("初始容量： " + elementDataLength);
        list.add("hello");

        int length = getElementDataLength(list);
        System.out.println("第一次添加后的容量： " + length);

        for (int i = 1; i <= 15 ; i++) {
            list.add("hello");
        }
        int length1 = getElementDataLength(list);
        System.out.println("第16次添加后的容量： " + length1);

    }

    //获取集合底层数组容量
    private static int getElementDataLength(ArrayList<String> list) {
        try {
            //1. 拿字节码
            Class clazz = list.getClass();
            Field elementData = clazz.getDeclaredField("elementData");
            elementData.setAccessible(true);

            Object[] obj = (Object[]) elementData.get(list);
            return obj.length;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }
}

